/*
 *  stmp.c
 *
 *  Very simple STMP mail send.  With STARTTLS and AUTH PLAIN 
 *  support (ie Encryption).
 *
 * Copyright (c) 2006 Karlan Thomas Mitchell<karlanmitchell@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, is prohibited except by
 * Karlan Thomas Mitchell.
 *
 * THIS SOFTWARE IS PROVIDED BY KARLAN THOMAS MITCHELL AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */ 

#include "smtp.h"



#ifndef SMTP_DEBUG
        int smtp_debug(const char * format, ...){
	     return 0;
	     }
#endif

int send_email_file(char * smtpserver, char * subject, char * from, char * password, char * to, char * filename){
    if(is_file(filename) == 0)
                         return -1;
                         
    off_t filesize = getfilesize(filename);
    char * message = (char *)malloc( (filesize + 1) * sizeof(char) );
    message[0] = 0;

    char buffer[1024];
    ssize_t rv;
    
    
    FILE * filed = fopen(filename, "r");
    off_t read = 0;
    while(!feof(filed) && read < filesize){
                        rv = fread(buffer, 1, 1023, filed);
                        if(rv <= 0)
                              break;
                        buffer[rv] = 0;
                        
                        strcat(message, buffer);
                        read += rv;
                        }
    fclose(filed);
    
    rv = send_email(smtpserver, subject, from, password, to, message);
    free(message);
    return rv;
    }
    
int send_email(char * smtpserver, char * subject, char * from, char * password, char * to, char * message){
	char server[1024];
	strcpy(server, smtpserver);

	char * ip = (char *)malloc( 1024 * sizeof(char) );
	int unsigned short port = 25;

	int is_ssl = 0;

	char * pntr;
	char * port_pntr;

         port_pntr = strchr(server, ':');
   	 if(port_pntr != NULL){
   		*(port_pntr) = 0;
   		*(port_pntr++);
   		port = atoi( port_pntr );
		}
	
	/*
	struct hostent * host_ent;
	host_ent = (struct hostent *)gethostbyname(server);

	
	if(host_ent != NULL)
		snprintf(ip, 1024, "%s", inet_ntoa(  *( struct in_addr*)( host_ent -> h_addr) )  );
	else 
		strcpy(ip, server);

	*/
	return send_email_bare(smtpserver, port, smtpserver, subject, from, password, to, message);
	}
	
int send_email_bare(char * ip, int short unsigned port, char * servername, char * subject, char * from, char * password, char * to, char * message){
    
    char from_email[1024];
    char * cpntr = strchr(from, '<');
    if(cpntr == NULL)
        strlcpy(from_email, from, 1024);
    else{
	*(cpntr++);
        strlcpy(from_email, cpntr, 1024);
	}
    cpntr = strchr(from_email, '>');
    if(cpntr != NULL)
	cpntr[0] = 0;
	

    struct st_psocket smtp_socket;

    smtp_socket.io_method = IO_BSD;


	if(psocket_connect(&smtp_socket, ip, port) == -1){
		return -1;
	}
	
	char  buffer[1024];
	
	psocket_readline_r(&smtp_socket, buffer, 1024);
	if(strncmp(buffer, "220", 3) != 0)
	                   return -1;
                    
        snprintf(buffer, 1024, "HELO %s\x0D\x0A", servername);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s\n", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);
	if(strncmp(buffer, "250", 3) != 0)
	                   return -1;
                    

	if(password != NULL){
	snprintf(buffer, 1024, "STARTTLS\x0D\x0A", from);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s\n", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);

	if(strncmp(buffer, "220", 3) == 0){
		char base64buf[1024];

		psocket_starttls(&smtp_socket);

		snprintf(buffer, 1024, "AUTH PLAIN\x0D\x0A");
		psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
		smtp_debug("C: %s\n", buffer);


		psocket_readline_r(&smtp_socket, buffer, 1024);
		smtp_debug("S: %s\n", buffer);
		if(strncmp(buffer, "334", 3) != 0)
			return -1;

		
		cpntr = strchr(from_email, '@');
		if(cpntr != NULL)
			cpntr[0] = 0;
		int user_name_len = strlen(from_email);
		snprintf(buffer, 1024, "X%sX%s", from_email, password);
		if(cpntr != NULL)
			cpntr[0] = '@';

		buffer[0] = 0;
		buffer[user_name_len + 1] = 0;

		b64_ntop(buffer, user_name_len + strlen(password) + 2, base64buf, 1024);


		psocket_fullsend(&smtp_socket, base64buf, strlen(base64buf));
		psocket_fullsend(&smtp_socket, "\x0D\x0A", 2);
		smtp_debug("C: %s\n", base64buf);


		psocket_readline_r(&smtp_socket, buffer, 1024);
		smtp_debug("S: %s\n", buffer);
		if(strncmp(buffer, "235", 3) != 0)
			return -1;

		
		
		}
	}/*password != NULL starttl part*/
	


	
        snprintf(buffer, 1024, "MAIL FROM:<%s>\x0D\x0A", from_email);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);


		
	if(strncmp(buffer, "250", 3) != 0)
	                   return -1;
 
 
        snprintf(buffer, 1024, "RCPT TO:<%s>\x0D\x0A", to);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);
	if(strncmp(buffer, "250", 3) != 0)
	                   return -1;
	                   
        snprintf(buffer, 1024, "DATA\x0D\x0A");
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);
	if(strncmp(buffer, "354", 3) != 0)
	                   return -1;
	                   
        snprintf(buffer, 1024, "Subject: %s\x0D\x0A", subject);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
        snprintf(buffer, 1024, "From: %s\x0D\x0A", from);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
        snprintf(buffer, 1024, "To: %s\x0D\x0A\x0D\x0A", to);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
	
	
	psocket_fullsend(&smtp_socket, message, strlen(message));
	smtp_debug("C: %s\n", message);
	                   
        snprintf(buffer, 1024, "\x0D\x0A.\x0D\x0A");
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);
	if(strncmp(buffer, "250", 3) != 0)
	                   return -1;
	                   
	        
	/*QUIT*/           
        snprintf(buffer, 1024, "QUIT\x0D\x0A", to);
	psocket_fullsend(&smtp_socket, buffer, strlen(buffer));
	smtp_debug("C: %s\n", buffer);
	psocket_readline_r(&smtp_socket, buffer, 1024);
	smtp_debug("S: %s\n", buffer);
	if(strncmp(buffer, "221", 3) != 0)
	                   return 0;
	
    return 0;
    }


